package SilkTest::Line;
use constant CBLOCK => '[+]'; # collapsed block
use constant EBLOCK => '[-]'; # expanded block
use constant LINE   => '[ ]'; # simple line marker

sub new {
    my ( $class, $raw_line, $absolute_num, $relative_num ) = @_;

    my $self = {
                 is_block      => 0,
                 ref_child     => [],
                 vars          => {},
                 marker        => undef,
                 # =====================
                 ref_parent    => undef,
                 # =====================
                 content       => undef, 
                 prev_line     => undef,
                 next_line     => undef,
                 absolute_num  => $absolute_num,
                 relative_num  => $relative_num,
                 indent        => undef
               };

    die($absolute_num) unless defined $raw_line;

    if ( $raw_line =~ /^(\s*)(\[[+\s-]\])\s(.*)$/ ) {
        my ( $indent, $marker, $content ) = (length($1), $2, $3);
        if ( $marker eq CBLOCK || $marker eq EBLOCK ) {
            $self->{is_block} = 1;
        }

        $self->{indent}   = $indent;
        $self->{marker}   = $marker;
        $self->{content}  = $content;
    }
    elsif ($raw_line =~ /^\s{4}(.*)$/) {
        $self->{content} = $1;
    }

    return bless $self, $class;
}

sub is_block {
    if ( defined $_[1] ) {
        $_[0]->{is_block} = $_[1];
    }
    return $_[0]->{is_block};
}

sub next_line {
    if ( defined $_[1] ) {
        $_[0]->{next_line} = $_[1];
    }
    return $_[0]->{next_line};
}

sub add_child {
    my ($self, $child) = @_;
    push @{$self->{ref_child}}, $child if defined $child;
}

sub parse_variable {
    my ($self, $variable, $value) = @_;
    my @subs_list;
    while ( $value =~ m/([^\$]?\$\w+)/g ) {
        my $var = $1;
        if ( my $val = $self->get_var_value($var) ) {
            $var = quotemeta($var);
            $value =~ s/$var/$val/;
        }
        else {
            print "Log: $var not defined\n";
        }
    }
    # concat text strings and remove spaces
    $value =~ s/^\s*//;
    $value =~ s/['"]\s*\+\s*['"]//g;

    $self->{vars}->{$variable} = $value;
    # print "$variable ===== $value\n";
}

sub set_content { shift->{'content'} = $_[0] }

sub get_var_value {
    my ( $self, $var_name ) = @_;
    
    my $value;
    unless ( $value = $self->{vars}->{$var_name} ) {
        if ( defined $self->{ref_parent} ) {
            $value = $self->{ref_parent}->get_var_value($var_name);
        }
        else {
            #print "Log: at root".$self->content."\n";
        }
    }
    return $value;
}

sub register {
    my ($self, $prev_line, $parent_block) = @_;
    $prev_line->next_line($self)    if defined $prev_line;
    if ( defined $parent_block ) {
        $parent_block->add_child($self);
        $self->{ref_parent} = $parent_block;
    }
}

sub content { shift->{content} };
sub indent  { shift->{indent}  };
sub marker  { shift->{marker}  };

1; # SilkTest::Line